package com.fas.hehe.system.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.collections.CollectionUtils;
import org.junit.Assert;

import com.fas.core.BaseService;
import com.fas.core.constant.R;
import com.fas.core.plugin.datatables.PageRequest;
import com.fas.core.plugin.jfinal.kit.ModelKit;
import com.fas.core.plugin.tree.jstree.Node;
import com.fas.core.util.sequence.Sequence;
import com.fas.hehe.system.model.Resource;
import com.fas.hehe.system.model.Role;
import com.fas.hehe.system.model.RoleOfResource;
import com.jfinal.aop.Before;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

public class RoleService extends BaseService {

	public Page<Record> queryPage(PageRequest request) {
		Assert.assertNotNull("请求参数不能为空", request);

		Map<String, Object> paramsMap = request.getParams();
		ArrayList<Object> params = new ArrayList<Object>();
		String selectSql = "select * ";
		StringBuffer whereSql = new StringBuffer();
		whereSql.append(" from sys_role where 1=1 ");

		if (StrKit.notBlank((String) paramsMap.get("id"))) {
			whereSql.append(" and id = ?");
			params.add(paramsMap.get("id"));
		}
		if (StrKit.notBlank((String) paramsMap.get("role"))) {
			whereSql.append(" and role like ?");
			params.add(this.getLikeValue(paramsMap.get("role")));
		}

		if (StrKit.notBlank((String) request.getOderby())) {
			whereSql.append(" order by ").append(request.getOderby());
		}

		return Db.paginate(request.getPageNumber(), request.getPageSize(), selectSql, whereSql.toString(),
				params.toArray());
	}

	// 根据角色编号得到角色标识符列表
	public Set<String> findRoles(Long... roleIds) {
		Set<String> roles = new HashSet<String>();
		for (Long roleId : roleIds) {
			Role role = findOne(roleId);
			if (role != null) {
				roles.add(role.getRole());
			}
		}
		return roles;
	}
	
	public Set<Long> findResourceIds(Set<Long> roleIds){
		HashSet<Long> resourceIds = new HashSet<Long>();
		if (CollectionUtils.isEmpty(roleIds)) {
			return resourceIds;
		}
		for (Long roleId : roleIds) {
			String sql = "select resource_id from sys_role_of_resource where role_id = ?";
			List<RoleOfResource> roleResourceList = RoleOfResource.dao.find(sql, roleId);
			for (RoleOfResource rr : roleResourceList) {
				resourceIds.add(rr.getResourceId());
			}
		}
		return resourceIds;
	}

	// 根据角色编号得到权限字符串列表
	public Set<String> findPermissions(Set<Long> roleIds) {
		return new ResourceService().findPermissions(this.findResourceIds(roleIds));
	}

	public Role findOne(Long roleId) {
		return Role.dao.findById(roleId);
	}

	public List<Role> findAll() {
		final String sql = "select * from sys_role";
		return Role.dao.find(sql);
	}

	public List<Role> findRolesByOrganizationId(Long orgId) {
		String sql = "select * from sys_role where organization_id = ?  and available =?";
		return Role.dao.find(sql, orgId ,R.Dict.STATUS_AVAILABLE);
	}
	
	public Node buildJstreeNode(Role role){
		Node node = new Node();
		if(R.Dict.IS_OR_NOT_Y.equals(role.getIsFixed()+"")){
			node.setText("[角色] "+role.getRole()+"(已锁定)");
		}else{
			node.setText("[角色] "+role.getRole());
		}
		
		node.setId("R_"+role.getId().toString());
		node.setType("role");
		node.addData("is_fixed", role.getIsFixed() == null ? "" : role.getIsFixed());
		
		return node;
	}
	
	public List<Node> loadOrgRoleTree(Long orgId){
		List<Role> roleList = this.findRolesByOrganizationId(orgId);
		List<Node> treeNodes = new ArrayList<Node>();
		for(Role role : roleList){
			treeNodes.add(buildJstreeNode(role));
		}
		return treeNodes;
	}
	
	
	public Role saveRole(Role role) {
		Long id = role.getId();
		if (id == null) {

			id = Sequence.getSequence();
			role.setId(id);
			role.setAvailable(Integer.valueOf(R.Dict.STATUS_AVAILABLE));
			role.save();
		} else {
			Role oldrole = Role.dao.findById(id);
			oldrole.setRole(role.getRole());
			oldrole.setDescription(role.getDescription());
			oldrole.update();
		}
		return role;
	}
	
	public boolean deleteRole(Long roleid){
		Role oldData = Role.dao.findById(roleid);
		Role newData = new Role();
		ModelKit.clone(oldData, newData);
		
		oldData.set("available", R.Dict.STATUS_UNAVAILABLE);
		oldData.update();
		this.saveOperateLog(R.OperType.UPDATE, newData, oldData, this.getLoginUser());
		return true;
	}
	
	/**
	 * 组织机构删除检查
	 * 			1、判断是否有用户关联当前角色
	 * @param orgId
	 * 			组织机构ID
	 * @return  BOOLEAN  
	 * 			{true: 允许删除, false:不允许删除}
	 */
	public boolean deleteRoleCheck(Long roleId){
		boolean allowDelete = true;
		Long relationNum = 0l;
		String sql = "select count(1) as num from sys_user_of_role where role_id = ?";
		Record rd1 = Db.findFirst(sql, roleId);
		relationNum = rd1.getLong("num");
		
		if(relationNum > 0)
			return false;											 
		
		return allowDelete;
	}
	
	public Long pareseTreeNodeId(String treeNodeId){
		String roleIdStr = treeNodeId.substring("R_".length(), treeNodeId.length());
		return Long.parseLong(roleIdStr);
	}
	
	public List<Node> loadResourceTreeByRole(Long roleId) {
		//查询当前登录用户所具备的资源权限
		Long userId = this.getLoginUser().getUserId();
		UserService userService = new UserService();
		Set<Long> maxResourceIdSet = userService.findResources(userId);
		
		//查询当前角色所具备的资源权限
		String sqlRR = "select * from sys_role_of_resource where role_id = ?";
		List<RoleOfResource> rorList = RoleOfResource.dao.find(sqlRR, roleId);
		Set<Long> hasResSet = new HashSet<Long>();
		for(RoleOfResource ror : rorList){
			hasResSet.add(ror.getResourceId());
		}
		
		String sql = "select * from sys_resource where FIND_IN_SET(id, queryChildrenResource(?))  and  available = ? order by priority asc";
		List<Resource> list = Resource.dao.findByCache(R.CacheName.GLOBAL_RES_DATA,R.Const.ROOT_RESID,sql, R.Const.ROOT_RESID,R.Dict.STATUS_AVAILABLE); // 后台根据父节点查询出的数据列表
		HashMap<Long, Resource> resMap = new HashMap<Long, Resource>();
		TreeMap<Long, List<Resource>> subResMap = new TreeMap<Long, List<Resource>>();
		for (Resource res : list) {
			Long id = res.getId();
			Long pid = res.getParentId();

			if (id != R.Const.ROOT_RESID) {
				List<Resource> subList = subResMap.get(pid);
				if (subList == null)
					subList = new ArrayList<Resource>();
				
				if(maxResourceIdSet.contains(id)){
					subList.add(res);
					subResMap.put(pid, subList);
				}
				
			}
			
			//当前登录管理员所具备权限
			if(maxResourceIdSet.contains(id)){
				resMap.put(id, res);
			}
		}

		List<Node> nodeList = new ArrayList<Node>();
		Node rootNode = buildTreeNode(R.Const.ROOT_RESID, subResMap, resMap,maxResourceIdSet,hasResSet);
		nodeList.add(rootNode);
		return nodeList;
	}

	/**
	 * 
	 * @Title:递归构建树jstree插件树形节点对象
	 * @Description:
	 * @param parentId
	 *            当前节点ID
	 * @param subResMap
	 *            {key: 资源IDLong,VALUE: 子节点列表List}
	 * @param resMap
	 *            {key: 资源IDLong,VALUE: 资源对象}
	 * @return
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月23日 下午2:09:12
	 */
	private Node buildTreeNode(Long parentId, TreeMap<Long, List<Resource>> subResMap, HashMap<Long, Resource> resMap,Set<Long> maxResourceIdSet,Set<Long> hasResSet) {
		List<Resource> subList = subResMap.get(parentId);
		Node node = new Node();

		if(!maxResourceIdSet.contains(parentId)){
			return null;
		}
		Resource res = resMap.get(parentId);
		Long resId = res.getId();
		String resName = res.getName();
		String resType = res.getType();
		node.setId(resId.toString());
		node.setText(resName);
		node.setType(resType);
		node.setOpened(true);
		node.setDisabled(true);
		//node.addData("icon_class", res.getIconClass());// 用户自定义数据
		//node.addData("permission", res.getPermission());
		
		if (CollectionUtils.isNotEmpty(subList)) {
			List<Node> childrenNodes = new ArrayList<Node>();
			for (Resource subRes : subList) {
				Long subResId = subRes.getId();
				Node e = this.buildTreeNode(subResId, subResMap, resMap,maxResourceIdSet,hasResSet);
				if(e != null)
					childrenNodes.add(e);
			}
			node.setChildren(childrenNodes);
			node.setSelected(false);
		}else{
			if(hasResSet.contains(resId)){
				node.setSelected(true);
			}
		}
		return node;
	}
	
	@Before(Tx.class)
	public boolean batchSaveRoleOfResource(Long roleId,String resourceIds){
		if(StrKit.isBlank(resourceIds) || resourceIds.indexOf(",") == -1){
			return true;
		}
		//先删除原有的资源权限
		String sql = "delete from sys_role_of_resource where role_id = ?";
		Db.update(sql, roleId);
		
		//保存新的资源权限
		List<RoleOfResource> list = new ArrayList<RoleOfResource>();
		String[] resIds = resourceIds.split(",");
		for(String resId :resIds){
			RoleOfResource ror = new RoleOfResource();
			ror.setRoleId(roleId);
			ror.setResourceId(Long.valueOf(resId));
			list.add(ror);
		}
		
		Db.batchSave(list, R.Const.DB_BATCH_SIZE);
		return true;
	}
	
}
